package com.pzhu.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pzhu.common.constant.Constant;
import com.pzhu.common.constant.ErrorCode;
import com.pzhu.mapper.MenuMapper;
import com.pzhu.mapper.RoleMapper;
import com.pzhu.mapper.UserMapper;
import com.pzhu.model.entity.Menu;
import com.pzhu.model.entity.Role;
import com.pzhu.model.entity.User;
import com.pzhu.model.help.ResponseResult;
import com.pzhu.service.UserService;
import com.pzhu.utils.JwtUtils;
import com.pzhu.utils.RedisUtil;
import com.pzhu.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author : zqh
 * @Date : 2023/11/26 0026 下午 3:42
 * @Version: 1.0
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public User getByUserName(String username) {
        return getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
    }

    @Override
    public String getUserAuthorityInfo(Long userId) {
        StringBuffer authority = new StringBuffer();

        if (redisUtil.hasKey(Constant.AUTHORITY_KEY + userId)) {
            System.out.println("有缓存");
            authority.append(redisUtil.get(Constant.AUTHORITY_KEY, String.valueOf(userId)));
        }else {
            System.out.println("没有缓存");
            // 获取角色
            List<Role> roleList = roleMapper.selectList(
                    new QueryWrapper<Role>().inSql("id","select role_id from hs_user_role where user_id = " + userId)
            );

            if (roleList.size() > 0) {
                String roleCodeStrs = roleList.stream()
                        .map(r -> "ROLE_" + r.getCode())
                        .collect(Collectors.joining(","));
                authority.append(roleCodeStrs);
            }

            // 获取菜单权限
            Set<String> menuCodeSet = new HashSet<String>();
            for (Role role : roleList) {
                List<Menu> menuList = menuMapper.selectList(
                        new QueryWrapper<Menu>().inSql("id", "select menu_id from hs_role_menu where role_id = "+role.getId())
                );
                for (Menu menu : menuList) {
                    String perms = menu.getPerms();
                    if (StringUtil.isNotEmpty(perms)){
                        menuCodeSet.add(perms);
                    }
                }
            }
            if (menuCodeSet.size() > 0) {
                authority.append(",");
                String menuCodeStrs = String.join(",", menuCodeSet);
                authority.append(menuCodeStrs);
            }
            redisUtil.set(Constant.AUTHORITY_KEY,String.valueOf(userId),authority,10*60);
            System.out.println("authority:"+authority.toString());
        }
        return authority.toString();
    }

    @Override
    public ResponseResult miniLogin(String openid) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getOpenId, openid));
        if (Objects.isNull(user)) {
            User newUser = new User();
            newUser.setUsername(Constant.WX_DEFAULT_NAME);
            newUser.setOpenId(openid);
            newUser.setPassword(bCryptPasswordEncoder.encode(Constant.DEFAULT_PASSWORD));
            int flag = baseMapper.insert(newUser);
            if (flag <= 0){
                return ResponseResult.error(ErrorCode.WX_ACCOUNT_ADD);
            }
            return ResponseResult.ok(createLoginResult(newUser, openid));
        }
        if (Constant.FORBIDDEN_STATE.equals(user.getStatus())) {
            return ResponseResult.error(ErrorCode.WX_ACCOUNT_BAN);
        }
        return ResponseResult.ok(createLoginResult(user, openid));
    }

    @Override
    public ResponseResult updateByOPenId(User user) {
        if (StringUtil.isEmpty(user.getOpenId())) {
            return ResponseResult.error(ErrorCode.WX_NEED_OPENID);
        }
        userMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getOpenId, user.getOpenId()));
        //查询
        User result = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getOpenId, user.getOpenId()));
        Map<String, Object> map = new HashMap<>();
        map.put("user", result);
        return ResponseResult.ok(map);
    }

    /**
     * 创建登陆返回值
     * @param user
     * @param openid
     * @return
     */
    private Map<String, Object> createLoginResult(User user, String openid) {
        String token = JwtUtils.genJwtToken(user.getUsername());
        Map<String, Object> map = new HashMap<>();
        map.put("token",token);
        map.put("userInfo",user);
        map.put("openid",openid);
        return map;
    }
}
